package com.wan.thread;

import io.netty.util.concurrent.DefaultThreadFactory;

import java.util.Map;
import java.util.concurrent.*;

/**
 * ExecutorService的线程池管理器
 * 没有特殊绑定线程的需求，推荐用这个
 */
public class ExecutorManager {

    private static final Map<String, ExecutorService> EXECUTE_MAP = new ConcurrentHashMap<>();

    public static final ExecutorConfig DEFAULT_CONFIG;

    static {
        int availableProcessors = Math.max(Runtime.getRuntime().availableProcessors(),4);
        DEFAULT_CONFIG = new ExecutorConfig(
                availableProcessors, availableProcessors * 2, 10,
                TimeUnit.MINUTES
        );
    }

    public static ExecutorService getExecutor(String type,ExecutorConfig config){
        if(config.threadFactory == null)
            config.threadFactory = new DefaultThreadFactory(type);
        if(config.workQueue == null){
            config.workQueue = new LinkedTransferQueue<>();
        }
        return EXECUTE_MAP.computeIfAbsent(type, t->{
            if(config.rejectedExecutionHandler == null){
                return new ThreadPoolExecutor(config.corePoolSize,config.maximumPoolSize,
                        config.keepAliveTime,config.timeUnit,
                        config.workQueue,config.threadFactory);
            }else{
                return new ThreadPoolExecutor(config.corePoolSize,config.maximumPoolSize,
                        config.keepAliveTime,config.timeUnit,
                        config.workQueue,config.threadFactory,config.rejectedExecutionHandler);
            }
        });
    }

    public static ExecutorService getExecutor(Type type,ExecutorConfig config){
        return getExecutor(type.name(),config);
    }



    /**
     * 获取默认的线程池
     */
    public static ExecutorService getDefaultExecutor(){
        return getExecutor(Type.DEFAULT,DEFAULT_CONFIG);
    }

    public static void destroy(){
        for (ExecutorService executorService : EXECUTE_MAP.values()) {
            if(!executorService.isShutdown()){
                executorService.shutdown();
            }
        }
    }


    public enum Type{
        DEFAULT,
        ASYNC,
        TIME_WHEEL,
    }

    public static class ExecutorConfig{
        //核心线程数
        public int corePoolSize;
        //线程池最大线程数
        public int maximumPoolSize;
        //线程存活时间
        public int keepAliveTime;
        //时间单位
        public TimeUnit timeUnit;
        //阻塞任务队列
        public BlockingQueue<Runnable> workQueue;
        //线程工厂
        public DefaultThreadFactory threadFactory;
        //拒绝策略
        public RejectedExecutionHandler rejectedExecutionHandler;

        public ExecutorConfig(int corePoolSize, int maximumPoolSize, int keepAliveTime,
                              TimeUnit timeUnit, BlockingQueue<Runnable> workQueue,
                              DefaultThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.keepAliveTime = keepAliveTime;
            this.timeUnit = timeUnit;
            this.workQueue = workQueue;
            this.threadFactory = threadFactory;
            this.rejectedExecutionHandler = rejectedExecutionHandler;
        }

        public ExecutorConfig(int corePoolSize, int maximumPoolSize, int keepAliveTime, TimeUnit timeUnit) {
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.keepAliveTime = keepAliveTime;
            this.timeUnit = timeUnit;
        }
    }

}